package com.li.test.base.jdkproxy;

import java.io.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class RpcJdkProxy {
    public static void export(Object service ,Integer port) throws IOException {
        ServerSocket server = null;
        server = new ServerSocket(port);
        System.out.println("服务端启动成功，监听端口8000，等待客户端连接。。。");
        while (true){
            Socket socket  = server.accept();//等待客户端连接

            new Thread(()->{
                ObjectOutputStream out = null;

                try {

                    while (true){
                        System.out.println("客户端连接成功：客户信息为："+socket.getRemoteSocketAddress());
                        ObjectInputStream in =new ObjectInputStream(socket.getInputStream());
                        HashMap map = (HashMap) in.readObject();

                        /*String methodname= String.valueOf(in.read());
                        Class<?>[] parmtypes = (Class<?>[])in.readObject();
                        Object[] argument = ( Object[])in.readObject();*/

                        Method method = service.getClass().getMethod(map.get("methodName").toString(),(Class<?>[])map.get("methodParameterTypes"));
                        Object res = method.invoke(service,( Object[])map.get("methodArgs"));
                        //向客户端写数据
                        out = new ObjectOutputStream(socket.getOutputStream());
                        out.writeObject(res);
                    }
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            }).start();
        }


    }


    public static  <T> T refer(Class<T> interfaceClass, String host, int
            port){
     //   HelloServiceImpl helloServiceImpl = new HelloServiceImpl();
        return  (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[] {interfaceClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Socket socket = new Socket(host, port); //指定
                //provider 的 ip 和端⼝
                Map<String,Object> objectMap = new HashMap<>();


                ObjectOutputStream output = new
                        ObjectOutputStream(socket.getOutputStream());
                objectMap.put("methodName",method.getName());
                objectMap.put("methodParameterTypes",method.getParameterTypes());
                objectMap.put("methodArgs",args);
                output.writeObject(objectMap);
               /* output.writeObject(method.getName()); //传⽅法名
                output.writeObject(method.getParameterTypes()); //传参
               // 数类型
                output.writeObject(args); //传参数值*/
                ObjectInputStream input = new
                        ObjectInputStream(socket.getInputStream());
                Object result = input.readObject(); //读取结果
                return result;
            }
        });
    }
}
